home *** CD-ROM | disk | FTP | other *** search
/ Nebula 1 / Nebula One.iso / Graphics / Multimedia / Movie3.0 / Source / xanim / xanim_fli.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-06-02  |  27.3 KB  |  965 lines

  1.  
  2. /*
  3.  * xanim_fli.c
  4.  *
  5.  * Copyright (C) 1990,1991,1992,1993,1994 by Mark Podlipec. 
  6.  * All rights reserved.
  7.  *
  8.  * This software may be freely copied, modified and redistributed without
  9.  * fee for non-commerical purposes provided that this copyright notice is
  10.  * preserved intact on all copies and modified copies.
  11.  * 
  12.  * There is no warranty or other guarantee of fitness of this software.
  13.  * It is provided solely "as is". The author(s) disclaim(s) all
  14.  * responsibility and liability with respect to this software's usage
  15.  * or its effect upon hardware or computer systems.
  16.  *
  17.  */
  18. #include "xanim_fli.h" 
  19.  
  20. extern ULONG fli_pad_kludge;
  21.  
  22. LONG Is_FLI_File();
  23. ULONG Fli_Read_File();
  24. static void FLI_Read_Header();
  25. ULONG FLI_Read_Frame_Header();
  26. FLI_FRAME *FLI_Add_Frame();
  27. ULONG FLI_Decode_BRUN();
  28. ULONG FLI_Decode_LC();
  29. ULONG FLI_Decode_COPY();
  30. ULONG FLI_Decode_BLACK();
  31. ULONG FLI_Decode_LC7();
  32. static void FLI_Read_COLOR();
  33.  
  34. XA_ACTION *ACT_Get_Action();
  35. XA_CHDR *ACT_Get_CMAP();
  36. void ACT_Add_CHDR_To_Action();
  37. void ACT_Setup_Mapped();
  38. void ACT_Get_CCMAP();
  39.  
  40.  
  41. void UTIL_Sub_Image();
  42. ULONG UTIL_Get_LSB_Long();
  43. ULONG UTIL_Get_LSB_Short();
  44.  
  45. static ColorReg fli_cmap[FLI_MAX_COLORS];
  46. static Fli_Header fli_hdr;
  47. static Fli_Frame_Header frame_hdr;
  48.  
  49. static FLI_FRAME *fli_frame_start,*fli_frame_cur;
  50. static ULONG fli_frame_cnt;
  51. static ULONG fli_imagex,fli_imagey,fli_imagec;
  52. static ULONG fli_max_fsize;
  53.  
  54. /* 
  55.  * FLI has time period of 1/70th sec where  FLC has time period of 1 ms.
  56.  */
  57. #define FLI_TIME_PERIOD   ((fli_hdr.magic == 0xaf11)?(14):(1))
  58.  
  59. static XA_CHDR *fli_chdr;
  60.  
  61. FLI_FRAME *FLI_Add_Frame(time,act)
  62. ULONG time;
  63. XA_ACTION *act;
  64. {
  65.   FLI_FRAME *fframe;
  66.  
  67.   fframe = (FLI_FRAME *) malloc(sizeof(FLI_FRAME));
  68.   if (fframe == 0) TheEnd1("FLI_Add_Frame: malloc err");
  69.  
  70.   fframe->time = time;
  71.   fframe->act = act;
  72.   fframe->next = 0;
  73.  
  74.   if (fli_frame_start == 0) fli_frame_start = fframe;
  75.   else fli_frame_cur->next = fframe;
  76.  
  77.   fli_frame_cur = fframe;
  78.   fli_frame_cnt++;
  79.   return(fframe);
  80. }
  81.  
  82. static void FLI_Free_Frame_List(fframes)
  83. FLI_FRAME *fframes;
  84. {
  85.   FLI_FRAME *ftmp;
  86.   while(fframes != 0)
  87.   {
  88.     ftmp = fframes;
  89.     fframes = fframes->next;
  90.     FREE(ftmp,0x2000);
  91.   }
  92. }
  93.  
  94. /*
  95.  *
  96.  */
  97. LONG Is_FLI_File(filename)
  98. char *filename;
  99. {
  100.   FILE *fin;
  101.   ULONG data;
  102.  
  103.   if ( (fin=fopen(filename,XA_OPEN_MODE)) == 0) return(XA_NOFILE);
  104.  
  105.   data = UTIL_Get_LSB_Long(fin);  /* read past size */
  106.   data = UTIL_Get_LSB_Short(fin); /* read magic */
  107.   fclose(fin);
  108.   if ( (data == 0xaf11) || (data == 0xaf12) ) return(TRUE);
  109.   return(FALSE);
  110. }
  111.  
  112.  
  113. static void FLI_Read_Header(fp,fli_hdr)
  114. FILE *fp;
  115. Fli_Header *fli_hdr;
  116. {
  117.   LONG i;
  118.  
  119.   fli_hdr->size   = UTIL_Get_LSB_Long(fp);
  120.   fli_hdr->magic  = UTIL_Get_LSB_Short(fp);
  121.   fli_hdr->frames = UTIL_Get_LSB_Short(fp);
  122.   fli_hdr->width  = UTIL_Get_LSB_Short(fp);
  123.   fli_hdr->height = UTIL_Get_LSB_Short(fp);
  124.   fli_hdr->res1   = UTIL_Get_LSB_Short(fp);
  125.   fli_hdr->flags  = UTIL_Get_LSB_Short(fp);
  126.   fli_hdr->speed  = UTIL_Get_LSB_Short(fp);
  127.   if (fli_hdr->speed <= 0) fli_hdr->speed = 1;
  128.   fli_hdr->next   = UTIL_Get_LSB_Long(fp);
  129.   fli_hdr->frit   = UTIL_Get_LSB_Long(fp);
  130.   for(i=0;i<102;i++) fgetc(fp);   /* ignore unused part of Fli_Header */
  131.  
  132.   fli_imagex=fli_hdr->width;
  133.   fli_imagey=fli_hdr->height;
  134.   if ( (fli_hdr->magic != 0xaf11) && (fli_hdr->magic != 0xaf12) )
  135.   {
  136.    fprintf(stderr,"imagex=%lx imagey=%lx\n",fli_imagex,fli_imagey);
  137.    fprintf(stderr,"Fli Header Error magic %lx not = 0xaf11\n",fli_hdr->magic);
  138.    TheEnd();
  139.   }
  140. }
  141.  
  142. ULONG FLI_Read_Frame_Header(fp,frame_hdr)
  143. FILE *fp;
  144. Fli_Frame_Header *frame_hdr;
  145. {
  146.   ULONG i;
  147.   UBYTE tmp[6];
  148.  
  149.   for(i=0;i<6;i++) tmp[i] = (UBYTE)fgetc(fp);
  150.  
  151.   DEBUG_LEVEL1 fprintf(stderr,"  magic = %02lx%02lx\n",tmp[5],tmp[4]);
  152.   while( !( (tmp[5]==0xf1) && ((tmp[4]==0xfa) || (tmp[4] == 0x00)) ) )
  153.   {
  154.     for(i=0;i<6;i++) tmp[i] = tmp[i+1];
  155.     tmp[5] = (UBYTE)fgetc(fp);
  156.     if (feof(fp)) return(0);
  157.   }
  158.  
  159.   frame_hdr->size = (tmp[0])|(tmp[1] << 8)|(tmp[2] << 16)|(tmp[3] << 24);
  160.   frame_hdr->magic = (tmp[4])|(tmp[5] << 8);
  161.   frame_hdr->chunks = UTIL_Get_LSB_Short(fp);
  162.   for(i=0;i<8;i++) fgetc(fp);    /* ignore unused part of Fli_Frame_Header */
  163.  
  164.   DEBUG_LEVEL1 
  165.     fprintf(stderr,"Frame Header size %lx  magic %lx  chunks %ld\n",
  166.         frame_hdr->size,frame_hdr->magic,frame_hdr->chunks);
  167.  
  168.   return(1);
  169. }
  170.  
  171. ULONG Fli_Read_File(fname,anim_hdr)
  172. char *fname;
  173. XA_ANIM_HDR *anim_hdr;
  174. {
  175.   FILE *fin;
  176.   LONG j,ret;
  177.   XA_ACTION *act;
  178.   UBYTE *pic;
  179.   ULONG pic_size,tmp_frame_cnt;
  180.   ULONG file_pos,frame_i;
  181.  
  182.   if ( (fin=fopen(fname,XA_OPEN_MODE)) == 0)
  183.   { 
  184.     fprintf(stderr,"can't open Fli File %s for reading\n",fname); 
  185.     return(FALSE);
  186.   }
  187.  
  188.   pic = 0;
  189.   fli_chdr = 0;
  190.   fli_frame_start = 0;
  191.   fli_frame_cur = 0;
  192.   fli_frame_cnt = 0;
  193.   fli_max_fsize = 0;
  194.  
  195.   FLI_Read_Header(fin,&fli_hdr);
  196.  
  197.   if (xa_verbose) fprintf(stderr,"   Size %ldx%ld Frames= %ld Magic= %lx\n",
  198.     fli_hdr.width, fli_hdr.height,fli_hdr.frames,fli_hdr.magic);
  199.  
  200.     /* Allocate image buffer so deltas may be applied if buffering */
  201.   pic_size = fli_imagex * fli_imagey;
  202.   if (xa_buffer_flag == TRUE)
  203.   {
  204.     pic = (UBYTE *) malloc( XA_PIC_SIZE(pic_size) );
  205.     if (pic == 0) TheEnd1("BufferAction: malloc failed");
  206.   }
  207.  
  208.  
  209.   tmp_frame_cnt = 0;
  210.   file_pos= 0x80;  /* need to do this because chunk sizes don't always
  211.             * add up to the frame size. */
  212.   while( FLI_Read_Frame_Header(fin, &frame_hdr) != 0)
  213.   {
  214.     ULONG fli_time,frame_read_size;
  215.  
  216.     file_pos += frame_hdr.size;
  217.     tmp_frame_cnt++;
  218.     fli_time = XA_GET_TIME(fli_hdr.speed * FLI_TIME_PERIOD);
  219.     
  220.     if (frame_hdr.magic == 0xf100)
  221.     {
  222.       LONG i;
  223.       DEBUG_LEVEL1 
  224.      fprintf(stderr,"FLI 0xf100 Frame: size = %lx\n",frame_hdr.size);
  225.       for(i=0;i<(frame_hdr.size - 16);i++) fgetc(fin);
  226.       if (frame_hdr.size & 0x01) fgetc(fin);
  227.     }
  228.     else if (frame_hdr.chunks==0)  /* this frame is for timing purposes */
  229.     {
  230.       DEBUG_LEVEL1 fprintf(stderr," FLI DELAY %ld\n",fli_hdr.speed);
  231.       act = ACT_Get_Action(anim_hdr,ACT_DELAY);
  232.       act->data = 0;
  233.       FLI_Add_Frame(fli_time,act);
  234.     }
  235.     else /* this frame has real data in it */
  236.     {
  237.       /* Loop through chunks in the frame
  238.        */
  239.       frame_read_size = 10;
  240.       for(j=0;j<frame_hdr.chunks;j++)
  241.       {
  242.         LONG chunk_size;
  243.     ULONG chunk_type;
  244.    
  245.     /* only last chunk in frame should have full time(j must stay signed)*/
  246.         if (j < (frame_hdr.chunks - 1) ) fli_time = 0;
  247.     else fli_time = XA_GET_TIME(fli_hdr.speed * FLI_TIME_PERIOD);
  248.         chunk_size = UTIL_Get_LSB_Long(fin) & 0xffffff;
  249.         chunk_type = UTIL_Get_LSB_Short(fin);
  250.     frame_read_size += 6 + chunk_size;
  251.     if ( (chunk_size & 0x01)&&(fli_pad_kludge==FALSE)) frame_read_size++;
  252.         DEBUG_LEVEL1 fprintf(stderr,"  chunk %ld) size %lx  type %lx tot %lx\n",
  253.         j,chunk_size,chunk_type,frame_read_size);
  254.         switch(chunk_type)
  255.         {
  256.           case CHUNK_4:     /* FLI Color with 8 bits RGB */
  257.         DEBUG_LEVEL1 fprintf(stderr," FLI COLOR(4)\n");
  258.         FLI_Read_COLOR(anim_hdr,fin,fli_time,8,frame_hdr.chunks);
  259.         break;
  260.           case FLI_COLOR:     /* FLI Color with 6 bits RGB */
  261.         DEBUG_LEVEL1 fprintf(stderr," FLI COLOR(11)\n");
  262.         FLI_Read_COLOR(anim_hdr,fin,fli_time,6,frame_hdr.chunks);
  263.         break;
  264.           case FLI_LC:
  265.           case FLI_LC7:
  266.           case FLI_BRUN:
  267.           case FLI_COPY:
  268.           case FLI_BLACK:
  269.         {
  270.           ACT_DLTA_HDR *dlta_hdr;
  271.          
  272.           if (chunk_type==FLI_COPY) chunk_size = pic_size;
  273.           else    chunk_size -= 6;
  274.  
  275.           act = ACT_Get_Action(anim_hdr,ACT_DELTA);
  276.           FLI_Add_Frame(fli_time,act);
  277.  
  278.           if ( (chunk_type == FLI_BLACK) && (chunk_size != 0) )
  279.                     TheEnd1("FLI BLACK: size err\n");
  280.           else if (chunk_size > 0)
  281.           {
  282.             if (xa_file_flag == TRUE)
  283.             {
  284.                dlta_hdr = (ACT_DLTA_HDR *) malloc(sizeof(ACT_DLTA_HDR));
  285.                if (dlta_hdr == 0) TheEnd1("FLI CHUNK: malloc failed");
  286.               act->data = (UBYTE *)dlta_hdr;
  287.               dlta_hdr->flags = ACT_SNGL_BUF;
  288.               dlta_hdr->fpos  = ftell(fin);
  289.               dlta_hdr->fsize = chunk_size;
  290.                fseek(fin,chunk_size,1); /* move past this chunk */
  291.               if (chunk_size > fli_max_fsize) 
  292.                     fli_max_fsize = chunk_size;
  293.             }
  294.             else
  295.             {
  296.                dlta_hdr = (ACT_DLTA_HDR *)
  297.                 malloc(sizeof(ACT_DLTA_HDR) + chunk_size);
  298.                if (dlta_hdr == 0) TheEnd1("FLI CHUNK: malloc failed");
  299.               act->data = (UBYTE *)dlta_hdr;
  300.               dlta_hdr->flags = ACT_SNGL_BUF | DLTA_DATA;
  301.               dlta_hdr->fpos = 0; dlta_hdr->fsize = chunk_size;
  302.                ret = fread( dlta_hdr->data, chunk_size, 1, fin);
  303.                if (ret != 1) TheEnd1("FLI DLTA: read failed");
  304.             }
  305.           }
  306.           else TheEnd1("FLI DLTA: invalid size");
  307.  
  308.           dlta_hdr->xpos = dlta_hdr->ypos = 0;
  309.           dlta_hdr->xsize = fli_imagex;
  310.           dlta_hdr->ysize = fli_imagey;
  311.           dlta_hdr->special = 0;
  312.           dlta_hdr->extra = 0;
  313.           switch(chunk_type)
  314.           {
  315.            case FLI_LC7:
  316.             DEBUG_LEVEL1 fprintf(stderr," FLI LC(7)\n");
  317.             dlta_hdr->delta = FLI_Decode_LC7;
  318.             break;
  319.           case FLI_LC:
  320.             DEBUG_LEVEL1 fprintf(stderr," FLI LC(12)\n");
  321.             dlta_hdr->delta = FLI_Decode_LC;
  322.             break;
  323.           case FLI_BLACK:
  324.             DEBUG_LEVEL1 fprintf(stderr," FLI BLACK(13)\n");
  325.             dlta_hdr->delta = FLI_Decode_BLACK;
  326.             break;
  327.           case FLI_BRUN:
  328.             DEBUG_LEVEL1 fprintf(stderr," FLI BRUN(15)\n");
  329.             dlta_hdr->delta = FLI_Decode_BRUN;
  330.             break;
  331.           case FLI_COPY:
  332.             DEBUG_LEVEL1 fprintf(stderr," FLI COPY(16)\n");
  333.             dlta_hdr->delta = FLI_Decode_COPY;
  334.             break;
  335.          }
  336.          ACT_Add_CHDR_To_Action(act,fli_chdr);
  337.          if (xa_buffer_flag == TRUE)
  338.          {
  339.            ULONG xpos,ypos,xsize,ysize,d_flag,map_flag;
  340.            map_flag = (x11_display_type & XA_X11_TRUE)?(TRUE):(FALSE);
  341.            d_flag = dlta_hdr->delta(pic,dlta_hdr->data,
  342.             dlta_hdr->fsize,0,fli_chdr->map,
  343.             map_flag, fli_imagex,fli_imagey,8,&xpos,&ypos,
  344.             &xsize,&ysize,0,0);
  345.            if (!(d_flag & ACT_DLTA_MAPD)) map_flag = FALSE;
  346.            FREE(dlta_hdr,0x2000); act->data = 0;
  347.            if (d_flag & ACT_DLTA_NOP) act->type = ACT_NOP;
  348.            else
  349.            {
  350.              xsize -= xpos; ysize -= ypos;
  351.              ACT_Setup_Mapped(act,pic,fli_chdr,
  352.             xpos,ypos,xsize,ysize,fli_imagex,fli_imagey,FALSE,0,
  353.             FALSE,TRUE,map_flag);
  354.            }
  355.          } /* end of buffer */
  356.         }
  357.         break;
  358.  
  359.           case FLI_MINI:
  360.         {
  361.           LONG i;
  362.           DEBUG_LEVEL1 fprintf(stderr," FLI MINI(18) ignored.\n");
  363.           for(i=0;i<(chunk_size-6);i++) fgetc(fin);
  364.           if ((fli_pad_kludge==FALSE)&&(chunk_size & 0x01)) fgetc(fin);
  365.         }
  366.         break;
  367.  
  368.            default: 
  369.              {
  370.                LONG i;
  371.            fprintf(stderr,"FLI Unsupported Chunk: type = %lx size=%lx\n",
  372.                     chunk_type,chunk_size);
  373.                for(i=0;i<(chunk_size-6);i++) fgetc(fin);
  374.            if ((fli_pad_kludge==FALSE)&&(chunk_size & 0x01)) fgetc(fin);
  375.              }
  376.              
  377.          break;
  378.         } /* end of switch */
  379.       } /* end of chunks is frame */
  380.     } /* end of not Timing Frame */
  381.     /* More robust way of reading FLI's. */
  382.     fseek(fin,file_pos,0);
  383.   } /* end of frames in file */
  384.   if (pic != 0) { FREE(pic,0x2000); pic=0;}
  385.   fclose(fin);
  386.  
  387.   /* extra for end and JMP2END */
  388.   anim_hdr->frame_lst = (XA_FRAME *)
  389.         malloc(sizeof(XA_FRAME) * (fli_frame_cnt + 2));
  390.   if (anim_hdr->frame_lst == NULL) TheEnd1("FLI_Read_Anim: malloc err");
  391.  
  392.   fli_frame_cur = fli_frame_start;
  393.   frame_i = 0;
  394.   while(fli_frame_cur != 0)
  395.   {
  396.     if (frame_i > fli_frame_cnt)
  397.     {
  398.       fprintf(stderr,"FLI_Read_Anim: frame inconsistency %ld %ld\n",
  399.                 frame_i,fli_frame_cnt);
  400.       break;
  401.     }
  402.     anim_hdr->frame_lst[frame_i].time = fli_frame_cur->time;
  403.     anim_hdr->frame_lst[frame_i].act = fli_frame_cur->act;
  404.     fli_frame_cur = fli_frame_cur->next;
  405.     frame_i++;
  406.   }
  407.   /* ADD JMP2END for FLI/FLC animations with a loop frame */
  408.   if ( (tmp_frame_cnt > fli_hdr.frames) && (frame_i > 1)
  409.       && (!(anim_hdr->anim_flags & ANIM_NOLOOP)) )
  410.   { 
  411.     anim_hdr->frame_lst[frame_i].time = anim_hdr->frame_lst[frame_i-1].time;
  412.     anim_hdr->frame_lst[frame_i].act  = anim_hdr->frame_lst[frame_i-1].act;
  413.     anim_hdr->frame_lst[frame_i-1].time = 0;
  414.     anim_hdr->frame_lst[frame_i-1].act = ACT_Get_Action(anim_hdr,ACT_JMP2END);
  415.     frame_i++;
  416.     anim_hdr->loop_frame = 1;
  417.   }
  418.   else anim_hdr->loop_frame = 0;
  419.   anim_hdr->last_frame = (frame_i>0)?(frame_i-1):(0);
  420.   anim_hdr->frame_lst[frame_i].time = 0;
  421.   anim_hdr->frame_lst[frame_i].act  = 0;
  422.   frame_i++;
  423.   anim_hdr->imagex = fli_imagex;
  424.   anim_hdr->imagey = fli_imagey;
  425.   anim_hdr->imagec = fli_imagec;
  426.   anim_hdr->imaged = 8; /* nop */
  427.   anim_hdr->max_fsize = fli_max_fsize;
  428.   FLI_Free_Frame_List(fli_frame_start);
  429.   if (xa_buffer_flag == FALSE) anim_hdr->anim_flags |= ANIM_SNG_BUF;
  430.   if (xa_file_flag == TRUE) anim_hdr->anim_flags |= ANIM_USE_FILE;
  431.   anim_hdr->fname = anim_hdr->name; /* data file is same as name */
  432.   return(TRUE);
  433. }
  434.  
  435.  
  436. /*
  437.  * Routine to Decode a Fli BRUN chunk
  438.  */
  439. ULONG
  440. FLI_Decode_BRUN(image,delta,dsize,chdr,map,map_flag,imagex,imagey,imaged,
  441.                     xs,ys,xe,ye,special,extra)
  442. UBYTE *image;        /* Image Buffer. */
  443. UBYTE *delta;        /* delta data. */
  444. ULONG dsize;            /* delta size */
  445. XA_CHDR *chdr;        /* color map info */
  446. ULONG *map;        /* used if it's going to be remapped. */
  447. ULONG map_flag;        /* whether or not to use remap_map info. */
  448. ULONG imagex,imagey;    /* Size of image buffer. */
  449. ULONG imaged;        /* Depth of Image. (IFF specific) */
  450. ULONG *xs,*ys;        /* pos of changed area. */
  451. ULONG *xe,*ye;        /* size of changed area. */
  452. ULONG special;        /* Special Info. */
  453. ULONG extra;        /* extra info needed to decode delta */
  454. {
  455.   ULONG i,j,k,packets,size,x,offset,pix_size;
  456.  
  457.   *xs = *ys = 0; *xe = imagex; *ye = imagey;
  458.   pix_size = (map_flag==TRUE)?x11_bytes_pixel:1;
  459.   for(i=0; i < imagey; i++)
  460.   {
  461.     offset = i * imagex;
  462.     packets = *delta++;
  463.  
  464.     x=0;
  465.     for(j= 0; j < packets; j++)
  466.     {
  467.       size = *delta++;
  468.       if (size & 0x80)         /* size < 0 so there is -size unique bytes */
  469.       {
  470.         size = 256-size; 
  471.         if (map_flag == TRUE)
  472.         {
  473.           if (pix_size == 4)
  474.             for(k=x;k<(x+size);k++)
  475.                 ((ULONG *)(image))[k+offset] = (ULONG)(map[*delta++]);
  476.           else if (pix_size == 2)
  477.             for(k=x;k<(x+size);k++)
  478.                 ((USHORT *)(image))[k+offset] = (USHORT)(map[*delta++]);
  479.           else
  480.             for(k=x;k<(x+size);k++)
  481.                 ((UBYTE *)(image))[k+offset] = (UBYTE)(map[*delta++]);
  482.         }
  483.         else
  484.         {
  485.           for(k=x;k<(x+size);k++)
  486.                 ((UBYTE *)(image))[k+offset] = (UBYTE)(*delta++);
  487.         }
  488.  
  489.         x += size;   
  490.       }
  491.       else                     /* size is pos repeat next byte size times */
  492.       {
  493.         ULONG d;
  494.         d = *delta++;
  495.         if (map_flag == TRUE)
  496.         {
  497.           if (pix_size == 4)
  498.             for(k=x;k<(x+size);k++)
  499.                 ((ULONG *)(image))[k+offset] = (ULONG)(map[d]);
  500.           else if (pix_size == 2)
  501.              for(k=x;k<(x+size);k++)
  502.                 ((USHORT *)(image))[k+offset] = (USHORT)(map[d]);
  503.           else
  504.              for(k=x;k<(x+size);k++)
  505.                 ((UBYTE *)(image))[k+offset] = (UBYTE)(map[d]);
  506.         }
  507.         else
  508.         {
  509.           for(k=x;k<(x+size);k++)
  510.                 ((UBYTE *)(image))[k+offset] = (UBYTE)(d);
  511.         }
  512.         x+=size;   
  513.       }
  514.     } /* end of packets per line */
  515.   } /* end of line */
  516.   if (map_flag) return(ACT_DLTA_MAPD);
  517.   else return(ACT_DLTA_NORM);
  518. }
  519.  
  520. /*
  521.  * Routine to Decode an Fli LC chunk
  522.  */
  523.  
  524. ULONG
  525. FLI_Decode_LC(image,delta,dsize,chdr,map,map_flag,imagex,imagey,imaged,
  526.                     xs,ys,xe,ye,special,extra)
  527. UBYTE *image;        /* Image Buffer. */
  528. UBYTE *delta;        /* delta data. */
  529. ULONG dsize;            /* delta size */
  530. XA_CHDR *chdr;        /* color map info */
  531. ULONG *map;        /* used if it's going to be remapped. */
  532. ULONG map_flag;        /* whether or not to use remap_map info. */
  533. ULONG imagex,imagey;    /* Size of image buffer. */
  534. ULONG imaged;        /* Depth of Image. (IFF specific) */
  535. ULONG *xs,*ys;        /* pos of changed area. */
  536. ULONG *xe,*ye;        /* size of changed area. */
  537. ULONG special;        /* Special Info. */
  538. ULONG extra;        /* extra info needed to decode delta */
  539. {
  540.   ULONG i,j,k,packets,size,x,offset;
  541.   ULONG start,lines,skip,minx,maxx,pix_size;
  542.  
  543.   pix_size = (map_flag==TRUE)?x11_bytes_pixel:1;
  544.   start = *delta++; start |= *delta++ << 8;  /* lines to skip */
  545.   lines = *delta++; lines |= *delta++ << 8;  /* number of lines */
  546.  
  547.   minx = imagex; 
  548.   maxx = 0;
  549.  
  550.   for(i=start;i<(start+lines);i++)
  551.   {
  552.     offset = i * imagex;
  553.     packets = *delta++;
  554.  
  555.     x=0;
  556.     for(j=0;j<packets;j++)
  557.     {
  558.       skip = *delta++;   /* this is the skip count */
  559.       size = *delta++;
  560.  
  561.       if (j==0) { if (skip < minx) minx = skip; }
  562.       x+=skip;
  563.       if (size & 0x80) /* next byte repeated -size times */
  564.       {
  565.         ULONG d;
  566.         size = 256-size; 
  567.         d = *delta++;
  568.     if (map_flag == TRUE)
  569.         {
  570.       if (pix_size == 4)
  571.             for(k=x;k<(x+size);k++) 
  572.         ((ULONG *)(image))[k+offset] = (ULONG)(map[d]);
  573.       else if (pix_size == 2)
  574.              for(k=x;k<(x+size);k++) 
  575.         ((USHORT *)(image))[k+offset] = (USHORT)(map[d]);
  576.       else
  577.              for(k=x;k<(x+size);k++) 
  578.         ((UBYTE *)(image))[k+offset] = (UBYTE)(map[d]);
  579.         }
  580.         else
  581.         {
  582.           for(k=x;k<(x+size);k++) 
  583.         ((UBYTE *)(image))[k+offset] = (UBYTE)(d);
  584.         }
  585.         x+=size;   
  586.       }
  587.       else if (size) /* size is pos */
  588.       {
  589.         if (map_flag == TRUE)
  590.         {
  591.           if (pix_size == 4)
  592.             for(k=x;k<(x+size);k++) 
  593.         ((ULONG *)(image))[k+offset] = (ULONG)(map[*delta++]);
  594.           else if (pix_size == 2)
  595.             for(k=x;k<(x+size);k++) 
  596.         ((USHORT *)(image))[k+offset] = (USHORT)(map[*delta++]);
  597.           else
  598.             for(k=x;k<(x+size);k++) 
  599.         ((UBYTE *)(image))[k+offset] = (UBYTE)(map[*delta++]);
  600.         }
  601.         else
  602.         {
  603.           for(k=x;k<(x+size);k++) 
  604.         ((UBYTE *)(image))[k+offset] = (UBYTE)(*delta++);
  605.         }
  606.  
  607.         x+=size;   
  608.       }
  609.     } /* end of packets per line */
  610.     if (x > maxx) maxx = x;
  611.   } /* end of line */
  612.  
  613.   if ( (lines==0) || (maxx <= minx) )
  614.       { *ys = *ye = *xs = *xe = 0; return(ACT_DLTA_NOP); }
  615.   if (xa_optimize_flag == TRUE)
  616.   {
  617.     *ys = start;
  618.     *ye = start + lines;
  619.     *xs = minx;
  620.     if (maxx > imagex) maxx=imagex;
  621.     if (maxx > minx) *xe = maxx;
  622.     else *xe = imagex;
  623.   }
  624.   else { *ys = 0; *ye = imagey; *xs = 0; *xe = imagex; }
  625.  
  626.   if (map_flag) return(ACT_DLTA_MAPD);
  627.   else return(ACT_DLTA_NORM);
  628. }
  629.  
  630. ULONG
  631. FLI_Decode_COPY(image,delta,dsize,chdr,map,map_flag,imagex,imagey,imaged,
  632.                     xs,ys,xe,ye,special,extra)
  633. UBYTE *image;        /* Image Buffer. */
  634. UBYTE *delta;        /* delta data. */
  635. ULONG dsize;            /* delta size */
  636. XA_CHDR *chdr;        /* color map info */
  637. ULONG *map;        /* used if it's going to be remapped. */
  638. ULONG map_flag;        /* whether or not to use remap_map info. */
  639. ULONG imagex,imagey;    /* Size of image buffer. */
  640. ULONG imaged;        /* Depth of Image. (IFF specific) */
  641. ULONG *xs,*ys;        /* pos of changed area. */
  642. ULONG *xe,*ye;        /* size of changed area. */
  643. ULONG special;
  644. ULONG extra;        /* extra info needed to decode delta */
  645. {
  646.   ULONG image_size = imagex * imagey;
  647.   *xs = *ys = 0; *xe = imagex; *ye = imagey;
  648.   if (map_flag)
  649.   {
  650.     if (x11_bytes_pixel == 4)
  651.     { ULONG *i_ptr = (ULONG *)image;
  652.       while(image_size--) *i_ptr++ = (ULONG)map[ *delta++ ];
  653.     }
  654.     else if (x11_bytes_pixel == 2)
  655.     { USHORT *i_ptr = (USHORT *)image;
  656.       while(image_size--) *i_ptr++ = (USHORT)map[ *delta++ ];
  657.     }
  658.     else
  659.     { UBYTE *i_ptr = (UBYTE *)image;
  660.       while(image_size--) *i_ptr++ = (UBYTE)map[ *delta++ ];
  661.     }
  662.   } 
  663.   else memcpy( (char *)image,(char *)delta,image_size);
  664.   if (map_flag) return(ACT_DLTA_MAPD);
  665.   else return(ACT_DLTA_NORM);
  666. }
  667.  
  668. ULONG
  669. FLI_Decode_BLACK(image,delta,dsize,chdr,map,map_flag,imagex,imagey,imaged,
  670.                     xs,ys,xe,ye,special,extra)
  671. UBYTE *image;        /* Image Buffer. */
  672. UBYTE *delta;        /* delta data. */
  673. ULONG dsize;            /* delta size */
  674. XA_CHDR *chdr;        /* color map info */
  675. ULONG *map;        /* used if it's going to be remapped. */
  676. ULONG map_flag;        /* whether or not to use remap_map info. */
  677. ULONG imagex,imagey;    /* Size of image buffer. */
  678. ULONG imaged;        /* Depth of Image. (IFF specific) */
  679. ULONG *xs,*ys;        /* pos of changed area. */
  680. ULONG *xe,*ye;        /* size of changed area. */
  681. ULONG special;
  682. ULONG extra;        /* extra info needed to decode delta */
  683. {
  684.   ULONG image_size = imagex * imagey;
  685.   *xs = *ys = 0; *xe = imagex; *ye = imagey;
  686.   if (map_flag)
  687.   {
  688.     ULONG black = map[0];
  689.     if (x11_bytes_pixel == 4)
  690.     { ULONG *i_ptr = (ULONG *)image;
  691.       while(image_size--) *i_ptr++ = (ULONG)black;
  692.     }
  693.     else if (x11_bytes_pixel == 2)
  694.     { USHORT *i_ptr = (USHORT *)image;
  695.       while(image_size--) *i_ptr++ = (USHORT)black;
  696.     }
  697.     else
  698.     { UBYTE *i_ptr = (UBYTE *)image;
  699.       while(image_size--) *i_ptr++ = (UBYTE)black;
  700.     }
  701.   } 
  702.   else memset( (char *)image,0,image_size);
  703.   if (map_flag) return(ACT_DLTA_MAPD);
  704.   else return(ACT_DLTA_NORM);
  705. }
  706.  
  707.  
  708. /*
  709.  * Routine to read an Fli COLOR chunk
  710.  */
  711. static void FLI_Read_COLOR(anim_hdr,fin,fli_time,cbits,num_of_chunks)
  712. XA_ANIM_HDR *anim_hdr;
  713. FILE *fin;
  714. ULONG fli_time,cbits;
  715. ULONG num_of_chunks;
  716. {
  717.  XA_ACTION *act;
  718.  ULONG k,l,c_index,packets,skip,colors,cnt;
  719.  ULONG mask;
  720.  
  721.  mask = (0x01 << cbits) - 1;
  722.  packets = UTIL_Get_LSB_Short(fin);
  723.  c_index = 0;
  724.  
  725.  DEBUG_LEVEL1 fprintf(stderr,"   packets = %ld\n",packets);
  726.  cnt=2;
  727.  for(k=0;k<packets;k++)
  728.  {
  729.   skip = fgetc(fin);
  730.   colors=fgetc(fin);
  731.   DEBUG_LEVEL1 fprintf(stderr,"      skip %ld colors %ld\n",skip,colors);
  732.   cnt+=2;
  733.   if (colors==0) colors=FLI_MAX_COLORS;
  734.   c_index += skip;
  735.   for(l = 0; l < colors; l++)
  736.   {
  737.    fli_cmap[c_index].red   = fgetc(fin) & mask;
  738.    fli_cmap[c_index].green = fgetc(fin) & mask;
  739.    fli_cmap[c_index].blue  = fgetc(fin) & mask;
  740.    DEBUG_LEVEL5 fprintf(stderr,"         %ld)  <%lx %lx %lx>\n", 
  741.           l,fli_cmap[l].red, fli_cmap[l].green,fli_cmap[l].blue);
  742.    c_index++;
  743.   } /* end of colors */
  744.   cnt+= 3 * colors;
  745.  } /* end of packets */
  746.             /* read pad byte if needed */
  747.  if ((fli_pad_kludge==FALSE)&&(cnt&0x01)) fgetc(fin);
  748.  
  749.  /* if only one chunk in frame this is a cmap change only */
  750.  if ( (num_of_chunks==1) && (fli_chdr != 0) )
  751.  {
  752.    act = ACT_Get_Action(anim_hdr,0);
  753.    ACT_Get_CCMAP(act,fli_cmap,FLI_MAX_COLORS,0,cbits,cbits,cbits);
  754.    FLI_Add_Frame(fli_time,act);
  755.    ACT_Add_CHDR_To_Action(act,fli_chdr);
  756.  }
  757.  else
  758.    fli_chdr = ACT_Get_CMAP(fli_cmap,FLI_MAX_COLORS,0,FLI_MAX_COLORS,0,
  759.                             cbits,cbits,cbits);
  760. }
  761.  
  762. /*
  763.  * Routine to Decode an Fli LC chunk
  764.  */
  765. ULONG
  766. FLI_Decode_LC7(image,delta,dsize,chdr,map,map_flag,imagex,imagey,imaged,
  767.                         xs,ys,xe,ye,special,extra)
  768. UBYTE *image;        /* Image Buffer. */
  769. UBYTE *delta;        /* delta data. */
  770. ULONG dsize;            /* delta size */
  771. XA_CHDR *chdr;        /* color map info */
  772. ULONG *map;        /* used if it's going to be remapped. */
  773. ULONG map_flag;        /* whether or not to use remap_map info. */
  774. ULONG imagex,imagey;    /* Size of image buffer. */
  775. ULONG imaged;        /* Depth of Image. (IFF specific) */
  776. ULONG *xs,*ys;        /* pos of changed area. */
  777. ULONG *xe,*ye;        /* size of changed area. */
  778. ULONG special;        /* Special Info. */
  779. ULONG extra;        /* extra info needed to decode delta */
  780. {
  781.   ULONG i,j,x,y;
  782.   ULONG lines,blocks,xoff,cnt,tmp_data0,tmp_data1;
  783.   ULONG minx,maxx,miny,pix_size,last_pixel,last_pix_flag;
  784.   UBYTE *ptr;
  785.   
  786.  
  787.   minx = imagex;
  788.   maxx = 0;
  789.   miny = imagey;
  790.  
  791.   pix_size = (map_flag==TRUE)?x11_bytes_pixel:1;
  792.   ptr = image;
  793.   y = 0;
  794.   lines = *delta++; lines |= *delta++ << 8;  /* # of lines encoded */
  795.  
  796.   DEBUG_LEVEL5 fprintf(stderr,"lines=%ld\n",lines);
  797.  
  798.   last_pix_flag = last_pixel = 0;
  799.   for(i=0; i < lines; i++)
  800.   {
  801.    
  802.     blocks = *delta++; blocks |= *delta++ << 8; 
  803.  
  804.     DEBUG_LEVEL5 fprintf(stderr,"     %ld) ",i);
  805.  
  806.     while(blocks & 0x8000)
  807.     {
  808.       /* Upper bits 11 - SKIP lines */
  809.       if (blocks & 0x4000)
  810.       {
  811.         blocks = 0x10000 - blocks;
  812.         y += blocks;
  813.         DEBUG_LEVEL5 fprintf(stderr,"     yskip %ld",blocks);
  814.       }
  815.       else /* Upper bits 10 - Last Pixel Encoding */
  816.       {
  817.         DEBUG_LEVEL5 fprintf(stderr,"     lastpixel %ld",blocks);
  818.         last_pix_flag = 1;
  819.         last_pixel = blocks & 0xff;
  820.       }
  821.       blocks = *delta++; blocks |= *delta++ << 8;
  822.     }
  823.  
  824.     DEBUG_LEVEL5 fprintf(stderr,"     blocks = %ld\n",blocks);
  825.  
  826.     if (xa_optimize_flag == TRUE) if (y < miny) miny = y;
  827.  
  828.     ptr = (UBYTE *)(image + (y*imagex*pix_size) );
  829.     x = 0;
  830.  
  831.     for(j=0; j < blocks; j++)
  832.     {
  833.       xoff = (ULONG) *delta++;  /* x offset */
  834.       cnt  = (ULONG) *delta++;  /* halfword count */
  835.       ptr += (xoff * pix_size);
  836.       x += xoff;
  837.  
  838.       DEBUG_LEVEL5 
  839.         fprintf(stderr,"          %ld) xoff %lx  cnt = %lx",j,xoff,cnt);
  840.  
  841.       if (cnt & 0x80)
  842.       {
  843.         cnt = 256 - cnt;
  844.         DEBUG_LEVEL5 fprintf(stderr,"               NEG %ld\n",cnt);
  845.         if (xa_optimize_flag == TRUE)
  846.         {  
  847.           if (x < minx) minx = x;
  848.           x += (cnt << 1);
  849.           if (x > maxx) maxx = x;
  850.         }
  851.  
  852.     if (map_flag == TRUE)
  853.         {
  854.           tmp_data0 = map[*delta++];
  855.           tmp_data1 = map[*delta++];
  856.           if (pix_size == 4)
  857.       { 
  858.         ULONG *ulp = (ULONG *)ptr;
  859.             while(cnt--) { *ulp++ = (ULONG)tmp_data0;
  860.                *ulp++ = (ULONG)tmp_data1; }
  861.         ptr = (UBYTE *)ulp;
  862.           }
  863.           else if (pix_size == 2)
  864.       { 
  865.         USHORT *usp = (USHORT *)ptr;
  866.         while(cnt--) { *usp++ = (USHORT)tmp_data0;
  867.                *usp++ = (USHORT)tmp_data1; }
  868.         ptr = (UBYTE *)usp;
  869.           }
  870.           else
  871.             while(cnt--) { *ptr++ = (UBYTE)tmp_data0;
  872.                            *ptr++ = (UBYTE)tmp_data1; }
  873.     }
  874.     else
  875.     {
  876.           tmp_data0 = *delta++;
  877.           tmp_data1 = *delta++;
  878.           while(cnt--) { *ptr++ = (UBYTE)tmp_data0;
  879.                          *ptr++ = (UBYTE)tmp_data1; }
  880.     }
  881.  
  882.       }
  883.       else
  884.       {   /* cnt is number of unique pairs of bytes */
  885.         DEBUG_LEVEL5 fprintf(stderr,"               POS %ld\n",cnt);
  886.         if (xa_optimize_flag == TRUE)
  887.         {
  888.           if (cnt == 1)  /* potential NOPs just to move x */
  889.           {
  890.             if ( (*ptr != *delta) || (ptr[1] != delta[1]) )  
  891.             {
  892.               if (x < minx) minx = x; 
  893.               x += (cnt << 1);
  894.               if (x > maxx) maxx = x;
  895.             }
  896.           }
  897.       else
  898.           {
  899.             if (x < minx) minx = x; 
  900.             x += (cnt << 1);
  901.             if (x > maxx) maxx = x;
  902.           }
  903.         }
  904.         if (map_flag == TRUE)
  905.         {
  906.           if (pix_size == 4)
  907.       { 
  908.         ULONG *ulp = (ULONG *)ptr;
  909.         while(cnt--) { *ulp++ = (ULONG)map[*delta++];
  910.                            *ulp++ = (ULONG)map[*delta++]; }
  911.         ptr = (UBYTE *)ulp;
  912.           }
  913.           else if (pix_size == 2)
  914.       { 
  915.         USHORT *usp = (USHORT *)ptr;
  916.         while(cnt--) { *usp++ = (USHORT)map[*delta++];
  917.                *usp++ = (USHORT)map[*delta++]; }
  918.         ptr = (UBYTE *)usp;
  919.           }
  920.           else
  921.              while(cnt--) { *ptr++ = (UBYTE)map[*delta++];
  922.                 *ptr++ = (UBYTE)map[*delta++]; }
  923.         }
  924.         else
  925.              while(cnt--) { *ptr++ = (UBYTE) *delta++;
  926.                 *ptr++ = (UBYTE) *delta++; }
  927.  
  928.       } 
  929.     } /* (j) end of blocks */
  930.     if (last_pix_flag) /* last pixel */
  931.     {
  932.         if (map_flag == TRUE)
  933.         {
  934.           if (pix_size == 4)
  935.         { ULONG *ulp = (ULONG *)ptr; *ulp = (ULONG)map[last_pixel];}
  936.           else if (pix_size == 2)
  937.         { USHORT *slp = (USHORT *)ptr; *slp = (USHORT)map[last_pixel];}
  938.           else { *ptr = (UBYTE)map[last_pixel]; }
  939.         }
  940.         else *ptr = (UBYTE)(last_pixel);
  941.         last_pix_flag = 0;
  942.     }
  943.     y++;
  944.   } /* (i) end of lines */
  945.  
  946.   if (xa_optimize_flag == TRUE)
  947.   {
  948.     if ( (maxx <= minx) || (y <= miny) )
  949.       { *ys = *ye = *xs = *xe = 0; return(ACT_DLTA_NOP); }
  950.     if (minx >= imagex) minx = 0;     *xs = minx;
  951.     if (miny >= imagey) miny = 0;     *ys = miny;
  952. /* POD NOTE: look into the +2 and +1 stuff */
  953.     maxx += 2;  if (maxx > imagex) maxx = imagex;
  954.     y += 1; if (y > imagey) y = imagey;
  955.     *xe = maxx;
  956.     *ye = y;
  957.   }
  958.   else { *xs = 0; *ys = 0; *xe = imagex; *ye = imagey; }
  959.   DEBUG_LEVEL1 fprintf(stderr,"      LC7: xypos=<%ld %ld> xysize=<%ld %ld>\n",
  960.          *xs,*ys,*xe,*ye);
  961.   if (map_flag) return(ACT_DLTA_MAPD);
  962.   else return(ACT_DLTA_NORM);
  963. }
  964.  
  965.